package com.xhj.mybatis.plugin;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * InterceptorChain
 *
 * @author XJks
 * @description InterceptorChain 类用于管理和应用多个拦截器（Interceptor）。拦截器可以对目标对象进行增强或修改，常用于插件机制。
 */
public class InterceptorChain {

    /**
     * 用于存储所有添加的拦截器，初始化为一个空的 ArrayList。
     */
    private final List<Interceptor> interceptors = new ArrayList<>();

    /**
     * 对目标对象依次应用所有拦截器的 plugin 方法。
     *
     * @param target 需要被拦截器处理的目标对象
     * @return 经过所有拦截器处理后的对象
     */
    public Object pluginAll(Object target) {
        // 遍历所有拦截器
        for (Interceptor interceptor : interceptors) {
            /**
             * TODO:
             *  1.每个拦截器对目标对象进行处理，结果作为下一个拦截器的输入
             *  2.后处理的拦截器会包裹前处理的拦截器，从而形成一个嵌套的代理结构
             *  3.最终返回的对象是经过所有拦截器处理后的结果，达到一个代理链的效果
             *  4.多个拦截器的代理效果:最先配置的拦截器先代理目标对象，然后形成一个整体对象，后面的拦截器然后代理这个整体对象，依此类推，所以方法的进入顺序是与配置顺序相反的，后配置的拦截器先执行intercept方法，先配置的拦截器后执行intercept方法，但是相关方法的执行效果却与配置顺序相同
             */
            target = interceptor.plugin(target);
        }
        // 返回最终处理后的对象
        return target;
    }

    /**
     * 向拦截器链中添加一个拦截器。
     *
     * @param interceptor 要添加的拦截器
     */
    public void addInterceptor(Interceptor interceptor) {
        interceptors.add(interceptor);
    }

    /**
     * 获取所有已添加的拦截器列表（只读，不可修改）。
     *
     * @return 拦截器的不可变列表
     */
    public List<Interceptor> getInterceptors() {
        return Collections.unmodifiableList(interceptors);
    }

}
